Математическое моделирование
Мажитов М. А.
Российский университет дружбы народов, Москва, Россия
16 февраля 2024
Справка о языках программирования:
Julia — высокоуровневый высокопроизводительный свободный язык программирования с динамической типизацией, созданный для математических вычислений. Эффективен также и для написания программ общего назначения. Синтаксис языка схож с синтаксисом других математических языков (например, MATLAB и Octave), однако имеет некоторые существенные отличия. Julia написан на Си, C++ и Scheme. Имеет встроенную поддержку многопоточности и распределённых вычислений, реализованные в том числе в стандартных конструкциях.
OpenModelica — свободное открытое программное обеспечение для моделирования, симуляции, оптимизации и анализа сложных динамических систем. Основано на языке Modelica. Активно развивается Open Source Modelica Consortium, некоммерческой неправительственной организацией. Open Source Modelica Consortium является совместным проектом RISE SICS East AB и Линчёпингского университета. По своим возможностям приближается к таким вычислительным средам как Matlab Simulink, Scilab xCos, имея при этом значительно более удобное представление системы уравнений исследуемого блока.
На море в тумане катер береговой охраны преследует лодку браконьеров. Через определенный промежуток времени туман рассеивается, и лодка обнаруживается на расстоянии 11,5 км от катера. Затем лодка снова скрывается в тумане и уходит прямолинейно в неизвестном направлении. Известно, что скорость катера в 3,5 раза больше скорости браконьерской лодки.
$$ \left[ \begin{array}{cl} {{x}\over{v}} = {{11,5 - x}\over{3,5v}}\\ {{x}\over{v}} = {{11,5 + x}\over{3,5v}} \end{array} \right. $$
Из данных уравнений можно найти расстояние, после которого катер начнёт раскручиваться по спирали. Для данных уравнений решения будут следующими: $x_1 = {{115}\over{45}}$, $x_2 = {{115}\over{25}}$. Задачу будем решать для двух случаев. После того, как катер береговой охраны окажется на одном расстоянии от полюса, что и лодка, он должен сменить прямолинейную траекторию и начать двигаться вокруг полюса удаляясь от него со скоростью лодки v. Для этого скорость катера раскладываем на две составляющие: $v_r = {dr\over dt} = v$ - радиальная скорость и $v_\tau = r{d\theta\over dt}$ - тангенциальная скорость.
$$ v_\tau = {{\sqrt{11,25}v}} $$
$$ \left\{ \begin{array}{cl} {dr\over dt} = v \\ r{d\theta\over dt} = {{\sqrt{11,25}v}} \end{array} \right. $$
с начальными условиями
$$ \left\{ \begin{array}{cl} \theta_0 = 0 \\ r_0 = x_1 = {{115}\over{45}} \end{array} \right. $$
или
$$ \left\{ \begin{array}{cl} \theta_0 = -\pi \\ r_0 = x_2 = {{115}\over{25}} \end{array} \right. $$
Исключая из полученной системы производную по t, можно перейти к следующему уравнению (с неизменными начальными условиями):
$$ {dr\over d\theta} = {r\over\sqrt{11,25}} $$
Решением этого уравнения с заданными начальными условиями и будет являться траектория движения катера в полярных координатах. [3]
К сожалению, OpenModelica не адаптирована к использованию полярных координат, поэтому адекватное отображение результатов данный задачи там невозможно. [2]
Решить дифференциальное уравнение, расписанное в постановке задачи лабораторной работы, поможет библиотека DifferentialEquations. Итоговые изображения в полярных координатах будут строиться через библиотеку Plots. [1]
using Plots
using DifferentialEquations
#Начальные условия
const a = 11.5
const n = 3.5
#r0 для двух случаев
const r0 = a/(n + 1)
const r0_2 = a/(n - 1)
#интервалы
const T = (0, 2*pi)
const T_2 = (-pi, pi)
function F(u, p, t)
return u / sqrt(n*n - 1)
end
# Первый случай: ОДУ для r0 и T
equat = ODEProblem(F, r0, T)
result = solve(equat, abstol=1e-8, reltol=1e-8)
dxR = rand(1:size(result.t)[1])
rAngles = [result.t[dxR] for i in 1:size(result.t)[1]]
#xoлст1
plt = plot(proj=:polar, aspect_ratio=:equal, dpi = 1000, legend=true, bg=:white)
#параметры для холста
plot!(plt, xlabel="theta", ylabel="r(t)", title="Задача о погоне - случай 1", legend=:outerbottom)
plot!(plt, [rAngles[1], rAngles[2]], [0.0, result.u[size(result.u)[1]]], label="Путь лодки", color=:blue, lw=1)
scatter!(plt, rAngles, result.u, label="", mc=:blue, ms=0.0005)
plot!(plt, result.t, result.u, xlabel="theta", ylabel="r(t)", label="Путь катера", color=:green, lw=1)
scatter!(plt, result.t, result.u, label="", mc=:green, ms=0.0005)
savefig(plt, "lab02_01.png")
# Второй случай: ОДУ для r0_2 и T_2
equat = ODEProblem(F, r0_2 , T_2)
result = solve(equat, abstol=1e-8, reltol=1e-8)
dxR = rand(1:size(result.t)[1])
rAngles = [result.t[dxR] for i in 1:size(result.t)[1]]
#xoлст2
plt1 = plot(proj=:polar, aspect_ratio=:equal, dpi = 1000, legend=true, bg=:white)
#параметры для холста
plot!(plt1, xlabel="theta", ylabel="r(t)", title="Задача о погоне - случай 2", legend=:outerbottom)
plot!(plt1, [rAngles[1], rAngles[2]], [0.0, result.u[size(result.u)[1]]], label="Путь лодки", color=:blue, lw=1)
scatter!(plt1, rAngles, result.u, label="", mc=:blue, ms=0.0005)
plot!(plt1, result.t, result.u, xlabel="theta", ylabel="r(t)", label="Путь катера", color=:green, lw=1)
scatter!(plt1, result.t, result.u, label="", mc=:green, ms=0.0005)
savefig(plt1, "lab02_02.png")
В результате работы программы создаются две фотографии с траекториями движения катера и лодки для двух случаев.
Мною были построены графики для обоих случаев. На них получилось отрисовать трактерию катера, траекторию лодки и получилось наглядно найти их точки пересечения. Мы успешно решили задачу о погоне.
Были изучены основы языков программирования Julia и OpenModelica. Освоены библиотеки этих языков, которые используются для построения графиков и решения дифференциальных уравнений. Поскольку OpenModelica не работает с полярными координатами, она пока что не была использована в данной лабораторной работе.
[1] Документация по Julia: https://docs.julialang.org/en/v1/
[2] Документация по OpenModelica: https://openmodelica.org/
[3] Решение дифференциальных уравнений: https://www.wolframalpha.com/